<?php
	class simpleSmarty{
		var $tag_left='<%';
		var $tag_right='%>';
		var $templates_dir='templates';
		var $compile_dir='compiled';
		var $compiled=true;
		var $tpl_vars=array();
		var $reg_special_char=array('\\','$','+','*','{','}','[',']','?','.','|','(',')');
		
		function __construct($args){
			if(isset($args)&&is_array($args)){
				if(isset($args['tag_left'])){
					$this->tag_left=$args['tag_left'];
				}
				if(isset($args['tag_right'])){
					$this->tag_right=$args['tag_right'];
				}
				if(isset($args['templates_dir'])){
					$this->templates_dir=$args['templates_dir'];
				}
				if(isset($args['compile_dir'])){
					$this->compile_dir=$args['compile_dir'];
				}
				if(isset($args['compiled'])){
					$this->compiled=$args['compiled'];
				}
			}
		}
		
		//模版变量赋值
		function assign($k,$v){
			$this->tpl_vars[$k]=$v;
		}
		
		//显示模版
		function display($file){
			$this->fetch($file,true);
		}
		
		//基本模版函数
		function fetch($file,$is_show=false){
			$path=($this->templates_dir).'/'.$file;
			$c_path=($this->compile_dir).'/'.md5($file).'.php';
			if(file_exists($path)){
				$content=file_get_contents($path);
				$content=$this->_foreach($content);
				$content=$this->_if($content);
				$content=$this->_display_notes($content);
				$content=$this->_var($content);
				$content=$this->_plugins($content);
				$c_header="<?php /* created on ".date("Y-m-d H:i:s")."	compiled from ".$file." */?>\r\n\r\n";
				if(!file_exists($c_path)||filemtime($c_path)<filemtime($path)){
					file_put_contents($c_path,$c_header.$content);
				}
				if($is_show){
					include_once($c_path);
				}else{
					if(ob_start()){//打开apache缓存
						ob_clean();
						include_once($c_path);//引入并运行编译的文件，结果将放入缓冲区
						$re=ob_get_contents();//获取缓冲区内容
						ob_end_clean();//关闭缓冲并清空缓冲区，缓冲区内的内容不会被输出
						return $re;
					}else{
						return '请先打开apache自带缓存，也可以通过设置php.ini参数[output_buffering=On]';
					}
				}
			}else{
				echo("模版文件".$path."不存在");
			}
		}

		//foreach语句替换
		private function _foreach($content){
			$start=$this->reg_filter($this->tag_left);
			$end=$this->reg_filter($this->tag_right);
			$reg=array(
				'/'.$start.'\s*foreach\s+from\s*=\s*\$([A-Za-z_][A-Za-z0-9_]*)\s+item\s*=\s*\$([A-Za-z_][A-Za-z0-9_]*)\s*'.$end.'/',
				'/'.$start.'\/foreach'.$end.'/'
			);
			$replace=array(
				'<?php foreach( $this->tpl_vars["${1}"] as $this->tpl_vars["${2}"]) { ?>',
				'<?php } ?>'
			);
			$content=preg_replace($reg,$replace,$content);
			return $content;
		}
		
		//if语句替换
		private function _if($content){
			$start=$this->reg_filter($this->tag_left);
			$end=$this->reg_filter($this->tag_right);
			$reg=array(
				'/'.$start.'\s*(if)\(([^\)]+)\)\s*'.$end.'/',
				'/'.$start.'\s*(elseif)\(([^\)]+)\)\s*'.$end.'/',
				'/'.$start.'\s*(else)\s*'.$end.'/',
				'/'.$start.'(\/if)'.$end.'/',
			);
			$if_callback=function ($m){//正则替换回调函数
				$reg_var=array(
					'/\$([A-Za-z_][A-Za-z0-9_]*)/'
				);
				$replace=array(
					'$this->tpl_vars["${1}"]'
				);
				$re=preg_replace($reg_var,$replace,$m[2]);
				switch($m[1]){
					case 'if':
						return '<?php if('.$re.'){?>';
						break;
					case 'elseif':
						return '<?php }elseif('.$re.'){?>';
						break;
					case 'else':
						return '<?php }else{?>';
						break;
					case '/if':
						return '<?php }?>';
						break;
					default:
						throw Exception('未知的标签'.$m[1]);
						break;
				}
			};
			$content=preg_replace_callback($reg,$if_callback,$content);
			return $content;
		}

		//变量替换
		private function _var($content){
			$start=$this->reg_filter($this->tag_left);
			$end=$this->reg_filter($this->tag_right);
			$reg=array('/'.$start.'\s*\$([A-Za-z_][A-Za-z0-9_]*)([^('.$end.')]*)'.$end.'/');
			$replace=array('<?php echo $this->tpl_vars["${1}"]${2};?>');
			$content=preg_replace($reg,$replace,$content);
			return $content;
		}

		//扩展替换
		private function _plugins($content){
			$start=$this->reg_filter($this->tag_left);
			$end=$this->reg_filter($this->tag_right);
			$reg=array(
				'/'.$start.'\s*([A-Za-z][A-Za-z0-9_]*)([^('.$end.')]*)'.$end.'/'	
			);
			$_plugin_callback=function($m){//正则回调函数
				$fun=$m[1];
				$path=(dirname(__FILE__)).'/plugins/'.$fun.'.php';
				if(file_exists($path)){
					$params=explode(' ',trim($m[2]));
					$args=array();
					for($i=0;$i<count($params);$i++){
						if(trim($params[$i])==''){
							continue;
						}
						$param=explode('=',$params[$i]);
						if(count($param)!=2){
							return '参数'.$params[$i].'书写不正确';
						}
						$param[0]=preg_replace('/['."'".'"]/','',$param[0]);//去出单引号和双引号
						$param[1]=preg_replace('/['."'".'"]/','',$param[1]);//去出单引号和双引号
						$args[$param[0]]=$param[1];
					}
					$str_args=serialize($args);
					require_once($path);
					$re='<?php echo '.$fun.'(unserialize(\''.$str_args.'\'),$this);?>';
					return $re;
				}else{
					return '引用的扩展不存在:'.$path;
				}
			};
			$content=preg_replace_callback($reg,$_plugin_callback,$content);
			return $content;
		}

		//注释语句
		private function _display_notes($content){
			$start=$this->reg_filter($this->tag_left);
			$end=$this->reg_filter($this->tag_right);
			$reg=array(
				'/'.$start.'\*/',//php注释开始
				'/\*'.$end.'/',//php注释结尾
				'/'.$start.'--/',//html注释开始
				'/--'.$end.'/'//html注释结尾
			);
			$replace=array(
				'<?php /* ',
				' */ ?>',
				'<!-- ',
				' -->'
			);
			$content=preg_replace($reg,$replace,$content);
			return $content;
		}

		//正则表达式特殊字符串替换
		private function reg_filter($str){
			foreach($this->reg_special_char as $v){
				$str=str_replace($v,'\\'.$v,$str);
			}
			return $str;
		}
	}
	

?>